#include "SImageButton.h"
#include "../core/ImageMgr.h"

#include <QMouseEvent>
#include <QStylePainter>
#include <QStyleOption>

SImageButton::SImageButton(QWidget* parent, QString imageId)
	: QWidget(parent),
	  m_useBgkColor(false),
	  m_mouseState(normal)
{
	if (!imageId.isEmpty())
	{
		setImgId(imageId);
	}
	setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
}

void SImageButton::mousePressEvent(QMouseEvent* event)
{
	m_mouseState = pressed;
	m_curImg = m_imgPressed ? m_imgPressed : m_curImg;
	update();
}

void SImageButton::mouseReleaseEvent(QMouseEvent* e)
{
	m_curImg = m_imgNormal;
	if(m_imgHover && rect().contains(e->localPos().toPoint()))
		m_curImg = m_imgHover ? m_imgHover : m_imgNormal;

	clicked(m_index);
	if (rect().contains(e->localPos().toPoint())) {
		m_mouseState = hover;
	}
	update();
}

void SImageButton::enterEvent(QEvent* event)
{
	m_mouseState = hover;
	if (m_imgHover)
	{
		m_curImg = m_imgHover;
	}
	update();
	enterOrLeaved(true);
}

void SImageButton::leaveEvent(QEvent* event)
{
	m_mouseState = normal;
	if (m_imgHover)
	{
		m_curImg = m_imgNormal;
	}
	update();
	enterOrLeaved(false);
}

void SImageButton::paintEvent(QPaintEvent* event)
{
	QStylePainter painter(this);

	//绘制背景色
	if (m_useBgkColor){
		if (isEnabled()){
			if (m_mouseState == normal) {
				painter.setBrush(QBrush(m_clrNormal));
			}
			else if (m_mouseState == hover) {
				painter.setBrush(QBrush(m_clrHover));
			}
			else if (m_mouseState == pressed) {
				painter.setBrush(QBrush(m_clrPressed));
			}
		} else {
			painter.setBrush(QBrush(m_clrDisabled));
		}
		painter.setPen(Qt::transparent);
		painter.setRenderHint(QPainter::Antialiasing);//抗锯齿
		painter.drawRoundedRect(rect(), 2, 2);
	}

	//绘制ICON图标
	if (!m_curImg)
	{
		painter.drawText(rect(), "No Img!");
		return;
	}

	QRect rcIcon = rect();
	int w = m_curImg->width();
	int h = m_curImg->height();
	rcIcon.setRect(rcIcon.left()+(rcIcon.width()-w)/2, rcIcon.top()+(rcIcon.height()-h)/2, w, h);

	painter.setRenderHint(QPainter::SmoothPixmapTransform);//处理图片失真
	if (isEnabled())
	{
		painter.drawImage(rcIcon, *m_curImg);
	}
	else
	{
		if (!m_imgDisabled)
		{
			QPixmap pm = QPixmap::fromImage(*m_imgNormal);
			QStyleOption opt;
			opt.initFrom(this);
			QPixmap pmDisabled = style()->generatedIconPixmap(QIcon::Disabled, pm, &opt);
			painter.drawPixmap(rcIcon, pmDisabled);
		}
		else
		{
			painter.drawImage(rcIcon, *m_imgDisabled);
		}
	}
}

QSize SImageButton::sizeHint() const
{
	if (!m_curImg)
		return QSize(20, 12);
	return m_curImg->size();
}

void SImageButton::setImg(SImage* img, ImgType type)
{
	switch (type)
	{
	case SImageButton::ImgType::kNormal:
		m_imgNormal = img;
		m_curImg = m_imgNormal;
		break;
	case SImageButton::ImgType::kHover:
		m_imgHover = img;
		break;
	case SImageButton::ImgType::kPressed:
		m_imgPressed = img;
		break;
	case SImageButton::ImgType::kDisabled:
		m_imgDisabled = img;
		break;
	default:
		break;
	}
}

//TODO: should consider how to update the image
//when window is moved to another screen with different dpi
//
void SImageButton::setImgId(QString imageId)
{
	if (imageId.isEmpty())
		return;

	m_imgNormal = ImgMgr::instance().image(imageId, WidgetStatus::kNormal, devicePixelRatioF());
	Q_ASSERT_X(m_imgNormal, "SImageButton", "Normal image is lost!");
	m_imgHover = ImgMgr::instance().image(imageId, WidgetStatus::kHover, devicePixelRatioF());
	m_imgPressed = ImgMgr::instance().image(imageId, WidgetStatus::kPressed, devicePixelRatioF());
	m_imgDisabled = ImgMgr::instance().image(imageId, WidgetStatus::kDisabled, devicePixelRatioF());

	m_curImg = m_imgNormal;
	if (rect().contains(mapFromGlobal(QCursor::pos())) && m_imgHover)
		m_curImg = m_imgHover;

	if(!isHidden())
		updateGeometry();
}

void SImageButton::setColor(QColor clrNormal, QColor clrHover, QColor clrPressed, QColor clrDisabled)
{
	m_useBgkColor = true;
	m_clrNormal = clrNormal;
	m_clrHover = clrHover;
	m_clrPressed = clrPressed;
	m_clrDisabled = clrDisabled;
	update();
}